class Dep{
  constructor(){
    this.subscribers = new Set()
  }

  addEffect(effect){
    this.subscribers.add(effect)
  }

  depend(){
    if(activeEffect){
      this.subscribers.add(activeEffect)
    }
  }

  notify(){
    this.subscribers.forEach(effect=>[
      effect()
    ])
  }
}

let activeEffect = null
function watchEffect(effect) {
  activeEffect = effect
  effect()
  activeEffect = null
}

const targetMap = new WeakMap()
function getDep(target,key){
  // 1.根据对象(target)取出相应的Map对象
  let depsMap = targetMap.get(target)
  if(!depsMap){
    depsMap = new Map()
    targetMap.set(target,depsMap)
  }

  // 2.取出具体的依赖对象
  let dep = depsMap.get(key)
  if(!dep){
    dep = new Dep()
    depsMap.set(key,dep)
  }

  return dep
}

// vue3的数据劫持
function reactive(raw){
  return new Proxy(raw,{
    get(target,key){
      const dep = getDep(target,key)
      dep.depend()
      return target[key]
    },
    set(target,key,newValue){
      if(target[key] !== newValue){
        const dep = getDep(target,key)
        target[key] = newValue
        dep.notify()
      }
    }
  })
}


// vue2对raw进行数据劫持
// function reactive(raw){
//   Object.keys(raw).forEach(key=>{

//     const dep = getDep(raw,key)
//     let value = raw[key]

//     Object.defineProperty(raw,key,{
//       get(){
//         dep.depend()
//         return value
//       },
//       set(newValue){
//         if(value !== newValue) {
//           value = newValue
//           dep.notify()
//         }
//       }
//     })
//   })

//   return raw
// }


// 测试
// const info = reactive({counter:100,name:'why'})
// const foo = reactive({height:1.88})


// watchEffect(function (){
//   console.log('effect1',info.counter *2,info.name)
// })

// watchEffect(function(){
//   console.log('effect2',info.counter * info.counter)
// })

// watchEffect(function(){
//   console.log('effect3',info.counter + 10,info.name)
// })

// watchEffect(function(){
//   console.log('effect4',foo.height)
// })

// info.counter++

// info.name = "lilei"
// info.name = "why"

// foo.height = 1.98
